home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char SccsId[]= "@(#)dp_manip.c V1.30 3/22/95";
- #endif
- /*
- | file -- dp_manip.c
- |====================================================================
- |
- | This program shows how to use DV-Tools to manipulate drawports.
- | The program loads in a previously created view and
- | presents a menu of choices to the user. The user may
- | pan the drawport to a selected point in the drawing;
- | she may zoom in or out by a factor of 2.0 (makes the
- | apparent size of the drawing twice as big or twice as small);
- | she may zoom to a specified area of the drawing;
- | and she may reset the drawport to its original state.
- | Also, this example shows how a call to TscReset is used to
- | reset the drawport after a window is resized (in a window
- | system).
- |
- | This example does not update dynamics or input objects.
- |
- | Select the QUIT option to exit the program.
- |
- |=====================================================================
- */
- #include <windows.h>
-
- /* DV-Tools header files */
- #include "std.h" /* <stdio.h> etc., scalar & macro definitions */
- #include "dvstd.h" /* public types & constants */
- #include "dvtools.h" /* constants used by T routines */
- #include "dvGR.h" /* constants used by window mgt & GR routines */
- #include "VOstd.h" /* constants used by VO & VOob routines */
- #include "Tfundecl.h" /* T routines (screens, drawports & views) */
- #include "VOfundecl.h" /* VO routines (objects) */
- #include "VUerfundecl.h" /* VUer routines (event handling routines) */
- #include "VUfundecl.h" /* VU routines (utilities) */
-
-
- /* Constants */
- #define DVPATH (char *)NULL
- #define DISPFORMS_STB (char *)NULL
- #define DVDEVICE (char *)NULL
- #define DVCOLORTABLE (char *)NULL
- #define VIEW_NAME "move_objs.v"
- #define SCREEN_VIEWPORT (RECTANGLE *)NULL
- #define ENTIRE_DRAWPORT (RECTANGLE *)NULL
- #define MENU_CLIENT (OBJECT)1
- #define VSCROLL_CLIENT (OBJECT)2
- #define HSCROLL_CLIENT (OBJECT)3
- #define ZOOM_IN (int)1
- #define ZOOM_OUT (int)2
- #define ZOOM_TO (int)3
- #define PAN (int)4
- #define RESET_DP (int)5
- #define QUIT (int)6
- #define EXPOSE_LABEL (int)1
- #define RESIZE_LABEL (int)2
-
- /* Information to be passed on to the service routine */
- typedef struct
- {
- DRAWPORT view_dp, main_dp;
- float *vscroll_data, *hscroll_data, *menu_data;
- OBJECT MessageString, menu_obj, hscroll_obj, vscroll_obj;
- DV_POINT CurrentCenter;
- int quit;
- } INFO;
-
- /* Whole world rectangle, (-16384, -16384) to (16383, 16383)*/
- LOCAL RECTANGLE whole_world =
- {XMIN, YMIN, XMAX, YMAX};
-
- /* Global forward function declarations */
- int ExposeResizeHandler V_P_((OBJECT scr_client, EVENT_REQUEST request,
- int label, OBJECT loc, ADDRESS args));
- int HandleInput V_P_((OBJECT client, EVENT_REQUEST er,
- int label, OBJECT loc, ADDRESS args));
-
- /* Local forward function declarations */
- LOCAL void ResetDrawport V_P_((INFO *info));
- LOCAL void PanDrawportTo V_P_((INFO *info, DV_POINT *newpt));
- LOCAL void Pan V_P_((INFO *info));
- LOCAL void UserZoomTo V_P_((INFO *info));
- LOCAL OBJECT GetLocationInDrawport V_P_((INFO *info, char *msg));
-
-
- /*
- * MAIN PROGRAM
- */
- int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow )
- {
- /*
- * program arguments
- * argv[1] - display device name (default is to use DVDEVICE)
- * argv[2] - view name (default is move_objs.v)
- */
-
- /* Define & initialize device name and view filename */
- char *device_name = DVDEVICE; /* default device name */
- char *view_name = VIEW_NAME; /* default view name */
-
- /* Define display variables */
- OBJECT screen; /* display device, the window */
- VIEW view, main_view; /* picture representation of the view file */
-
- /* Control loop variables */
- OBJECT location; /* the event representation */
- char key;
-
- /* Input object related variables */
- OBJECT drawing; /* graphical representation of screen */
- ADDRESS *vdplist; /* variable descriptor list for menu */
- int numvars; /* number of vdps in list */
- INFO info; /* struct passed to service result routine */
- int event_req_status; /* status of event requests */
-
- /* Layout rectangle variables */
- RECTANGLE box, /* world coordinate drawport area */
- svp_delta, /* allowance for line thickness */
- vvp; /* virtual coordinate drawport area */
-
- /* Other variables */
- OBJECT off_color; /* color object represent off drawing color */
-
- int argc;
- char **argv;
-
- make_argv(&argc,&argv,GetCommandLine());
-
- /*--------------------
- * Initialization
- *
- * TInit: perform the initialization of DV-Tools
- * TInit reads your configuration file and any
- * environment variables or logical names set.
- */
- TInit (DVPATH, DISPFORMS_STB);
-
- /*
- * TscOpenSet: open a device as a screen object using
- * specified attributes
- *
- * Set exposure block to YES to insure the window
- * is ready for drawing when TdpDraw is called.
- */
- if (argc > 1)
- device_name = argv[1];
- screen = TscOpenSet (device_name, DVCOLORTABLE,
- V_X_EXPOSURE_BLOCK, YES,
- V_ACTIVE_CURSOR, V_END_OF_LIST);
- if (!screen)
- {
- printf ("Must specify device on command line or");
- printf (" in DataViews configuration file.\n");
- S_EXIT (EXIT_ERR);
- }
-
- /*
- * VOscWinEventMask: sets the screen's window event mask
- */
- VOscWinEventMask ((ULONG) V_KEYPRESS | V_BUTTONPRESS
- | V_EXPOSE | V_RESIZE | V_MOTIONNOTIFY,
- (ULONG) 0);
-
- /*
- * VUerWinEventPost: Posts a request for a window event.
- *
- * Post event requests for "window" events - Expose and Resize.
- */
- VUerWinEventPost (screen, (VUERFCNFUNPTR)ExposeResizeHandler,
- (ADDRESS) NULL, 0, EXPOSE_LABEL,
- (ULONG) VUER_EXPOSE_EVENT);
- VUerWinEventPost (screen, (VUERFCNFUNPTR)ExposeResizeHandler,
- (ADDRESS) NULL, 0, RESIZE_LABEL,
- (ULONG) VUER_RESIZE_EVENT);
-
- /*
- * TviLoad: Load a view in from a file, either a
- * user supplied view or default view file move_objs.v
- */
- if (argc == 3)
- view_name = argv[2];
- view = TviLoad (view_name);
- if (!view)
- {
- printf ("Could not load view from file ");
- printf ("%s.\n", view_name);
- S_EXIT (EXIT_ERR);
- }
-
- /* Set the off drawing color to be used. This is done to show
- * the off drawing area when zooming and panning operations
- * are performed.
- */
- off_color = VOcoCreate (COLOR_COMPONENTS, 165, 165, 165);
- VOdrOffcolor (off_color);
-
- /* Load the control view and create a drawport to fit the entire screen.*/
- main_view = TviLoad ("dp_manip.v");
- info.main_dp = TdpCreateStretch (screen, main_view,
- SCREEN_VIEWPORT, &whole_world);
-
- /*
- * Get drawing object. Then obtain the object called MessageString
- * from the drawing and save it in the structure, info.
- */
- drawing = TviGetDrawing (main_view);
- info.MessageString = TdrGetNamedObject (drawing, "MessageString");
-
- /*
- * TdrGetNamedObject: Get a named object from a drawing
- * VOobBox: Get an object's bounding box
- * gets the rectangular area where the drawport will be
- * shown (may ignore svp_delta in this case)
- *
- * Create a display drawport using the view area's bounding box.
- */
- VOobBox (TdrGetNamedObject (drawing, "view.area"), &box, &svp_delta);
-
- /* Convert from world to virtual coordinates. */
- vvp.ll.x = box.ll.x + XMAX;
- vvp.ll.y = box.ll.y + YMAX;
- vvp.ur.x = box.ur.x + XMAX;
- vvp.ur.y = box.ur.y + YMAX;
-
- /*
- * TdpCreateStretch: Create a drawport
- * "drawport" is attached to the screen object, "screen"
- * "view[i]" is the view to be displayed on the screen
- * "vvp" specifies the screen viewport, here the
- * rectangular area named area_name[i]
- * "whole_world" specifies the portion of the view to be
- * displayed, here the whole view
- * The whole view will be stretched to fit in the drawport
- */
- info.view_dp = TdpCreateStretch (screen, view, &vvp, &whole_world);
-
- /* Erase the screen and draw the contents of both drawports */
- TscErase (screen);
- TdpDraw (info.main_dp);
- TdpDraw (info.view_dp);
-
- /*
- * Get the text menu input object and the scroll bars.
- * Obtain the vdp lists for the input objects then find
- * the data source variable which each vdp is linked to.
- * Next, obtain the buffer address which the data source
- * variable is pointing to. Finally, post service result
- * requests to monitor the interaction with the input objects.
- */
- info.menu_obj = TdrGetNamedObject (drawing, "menu");
- VOinGetVarList (info.menu_obj, &vdplist, &numvars);
- info.menu_data =
- (float *) TdsvGetBuffer (TvdGetDataSourceVariable (vdplist[0]));
-
- VUerServiceResultPost (MENU_CLIENT, (VUERFCNFUNPTR)HandleInput,
- (ADDRESS) & info, 0, info.menu_obj,
- INPUT_DONE, 0);
-
- info.vscroll_obj = TdrGetNamedObject (drawing, "vert_scroll");
- VOinGetVarList (info.vscroll_obj, &vdplist, &numvars);
- info.vscroll_data =
- (float *) TdsvGetBuffer (TvdGetDataSourceVariable (vdplist[0]));
-
- VUerServiceResultPost (VSCROLL_CLIENT, (VUERFCNFUNPTR)HandleInput,
- (ADDRESS) & info, 0, info.vscroll_obj,
- INPUT_DONE | INPUT_ACCEPT, 0);
-
- info.hscroll_obj = TdrGetNamedObject (drawing, "horz_scroll");
- VOinGetVarList (info.hscroll_obj, &vdplist, &numvars);
- info.hscroll_data =
- (float *) TdsvGetBuffer (TvdGetDataSourceVariable (vdplist[0]));
-
- VUerServiceResultPost (HSCROLL_CLIENT, (VUERFCNFUNPTR)HandleInput,
- (ADDRESS) & info, 0, info.hscroll_obj,
- INPUT_DONE | INPUT_ACCEPT, 0);
-
- /* Initialize scale and center value and quit flag */
- info.CurrentCenter.x = 0;
- info.CurrentCenter.y = 0;
- info.quit = NO;
- FOREVER
- {
- location = VOloWinEventPoll (V_WAIT);
- event_req_status = VUerHandleLocEvent (location);
-
- /*
- * If the return value of VUerHandleLocEvent is INPUT_UNUSED
- * then check for keypress or buttonpress events which
- * represent one of the exit keys.
- */
- if (event_req_status == INPUT_UNUSED)
- {
- /*
- * VOloType: returns the type of event. These types
- * match event types specified in VOscWinEventMask.
- */
- switch (VOloType (location))
- {
- case V_KEYPRESS:
- /*
- * Check key selected.
- * If the key symbol represents the characters 'q'
- * or 'Q' then exit the program.
- */
- key = VOloKey (location);
- if (key == '\014')
- {
- TscReset (screen);
- TdpDraw (info.main_dp);
- TdpDraw (info.view_dp);
- }
- else if (key == 'q' || key == 'Q')
- info.quit = YES;
- break;
-
- case V_BUTTONPRESS:
- /*
- * Check button selected.
- * The right mouse button exits the program.
- */
- switch (VOloButton (location))
- {
- case 3:
- info.quit = YES;
- break;
-
- default:
- break;
- }
- break;
-
- default:
- break;
- }
- }
-
- if (info.quit == YES)
- break;
- TdpDrawNext (info.main_dp);
- }
-
- /*--------------------
- * Termination
- *
- * TscErase: Erase the entire screen in the default
- * background color
- * TdpDestroy: Destroy the drawport,
- * TviDestroy: Destroy the view, freeing the allocated memory
- * TscCloseCurrentScreen: Close the current display screen
- * TTerminate: Perform the clean-up for DV-Tools
- */
- TscErase (screen);
- TdpDestroy (info.main_dp);
- TdpDestroy (info.view_dp);
- TviDestroy (view);
- TviDestroy (main_view);
- TscCloseCurrentScreen ();
- TTerminate ();
- return EXIT_OK;
- }
-
-
- /*--------------------
- * ExposeResizeHandler -- Service Routine which is called in
- * response to "window" events (Expose and Resize). The
- * event requests that this routine services are posted
- * with VUerWinEventPost (above). The "label" argument
- * tells the routine which request (Expose or Resize)
- * caused the routine to be called.
- */
- /*ARGSUSED*/
- int
- ExposeResizeHandler (scr_client, request, label, loc, args)
- OBJECT scr_client;
- EVENT_REQUEST request;
- int label;
- OBJECT loc;
- ADDRESS args;
- {
- switch (label)
- {
- /*
- * VOloRegion: Returns a rectangle representing the
- * exposed region on the screen.
- * TscRedraw: After erasing, redraws all the drawports
- * in the screen.
- * A portion of the window has been exposed and needs
- * to be redrawn.
- */
- case EXPOSE_LABEL:
- TscRedraw (scr_client, VOloRegion (loc));
- break;
-
- /*
- * The window size has been changed.
- * TscReset: Resets all screen drawports after
- * window resizing
- */
- case RESIZE_LABEL:
- TscReset (scr_client);
- break;
- }
-
- return INPUT_USED;
- }
-
- /*--------------
- * HandleInput -- Perform the appropriate action based
- * on the user's interaction with the particular
- * input object. This function is called for the
- * menu and scrollbars used in the control view.
- */
- /*ARGSUSED*/
- int
- HandleInput (client, er, label, loc, args)
- OBJECT client; /* client id posting service result req */
- EVENT_REQUEST er; /* service result posting routine return value */
- int label; /* label to identify service result request */
- OBJECT loc; /* location object */
- ADDRESS args; /* argument structure */
- {
- INFO *info = (INFO *) args;
- DV_POINT desired_center;
-
- switch ((int) client)
- {
- case MENU_CLIENT:
- switch ((int) (*info->menu_data))
- {
- case ZOOM_IN:
- TdpZoom (info->view_dp, (double) 2.0);
- break;
- case ZOOM_OUT:
- TdpZoom (info->view_dp, (double) 0.5);
- break;
- case ZOOM_TO:
- UserZoomTo (info);
- break;
- case PAN:
- Pan (info);
- break;
- case RESET_DP:
- ResetDrawport (info);
- break;
- case QUIT:
- info->quit = YES;
- break;
- }
-
- /* modify sliders' buffers so sliders will reflect change */
- *info->hscroll_data = -1 * info->CurrentCenter.x;
- *info->vscroll_data = -1 * info->CurrentCenter.y;
-
- /* set menu buffer to unhighlight button just pressed */
- *info->menu_data = 0;
- break;
-
- case VSCROLL_CLIENT:
- desired_center.x = info->CurrentCenter.x;
- desired_center.y = (DV_COORD) *info->vscroll_data * -1;
- PanDrawportTo (info, &desired_center);
- break;
-
- case HSCROLL_CLIENT:
- desired_center.x = (DV_COORD) *info->hscroll_data * -1;
- desired_center.y = info->CurrentCenter.y;
- PanDrawportTo (info, &desired_center);
- break;
- }
-
- if (!info->quit)
- TdpRedraw (info->view_dp, ENTIRE_DRAWPORT, YES);
-
- return INPUT_USED;
- }
-
- /*----------------
- * ResetDrawport -- User selected to Reset the view
- * drawport. Return the view drawport to the original
- * display. Reset the current scale and center point.
- */
- LOCAL void
- ResetDrawport (info)
- INFO *info;
- {
- info->CurrentCenter.x = 0;
- info->CurrentCenter.y = 0;
- TdpZoomTo (info->view_dp, ENTIRE_DRAWPORT);
- }
-
-
- /*----------------
- * PanDrawportTo -- Pan the drawport to the passed
- * center point.
- */
- LOCAL void
- PanDrawportTo (info, newpt)
- INFO *info;
- DV_POINT *newpt;
- {
- info->CurrentCenter.x = newpt->x;
- info->CurrentCenter.y = newpt->y;
- TdpPan (info->view_dp, newpt);
- }
-
-
- /*--------------
- * Pan -- Pan the drawport to the specified
- * center point.
- */
- LOCAL void
- Pan (info)
- INFO *info;
- {
- OBJECT location;
- DV_POINT *center_pt;
-
- /* Obtain a location for the center point from the user. */
- location = GetLocationInDrawport (info, "Select new center point.");
-
- /* Obtain the world coordinates of the location point. If the user
- selected a point outside the drawing area, the world coordinates
- of the location object will be NULL. In this case, we reprompt
- the user for another center point selection. */
- while (!(center_pt = (DV_POINT *) VOloWcpGet (location)))
- location = GetLocationInDrawport (info,
- "Invalid point selection.\nPick center point in drawing area.");
-
- /* Pan the drawport with the user selected center point. */
- PanDrawportTo (info, center_pt);
- }
-
- /*--------------
- * UserZoomTo -- User selected to Zoom To a particular region.
- * The user is prompted for the rectangle representing the
- * region to zoom to. TdpZoomTo is called to alter the
- * drawport display based on the selected rectangle.
- */
- LOCAL void
- UserZoomTo (info)
- INFO *info;
- {
- char *old_msg;
- OBJECT location;
- RECTANGLE ZoomVp;
- DV_POINT *point;
-
- old_msg = VUstrClone (VOtxGetString (info->MessageString));
- TdpEraseObject (info->main_dp, info->MessageString);
- VOtxSetString (info->MessageString, " ");
-
- /* Prompt user for first corner of area to zoom. A point
- selected outside of the drawing area is an invalid point
- selection and the user is reprompt for a selection. */
- location = GetLocationInDrawport (info,
- "Select first corner of area to zoom.");
- while (!(point = (DV_POINT *) VOloWcpGet (location)))
- location = GetLocationInDrawport (info,
- "Invalid point selection.\n Pick corner point in drawing area.");
- ZoomVp.ll.x = point->x;
- ZoomVp.ll.y = point->y;
-
- /* Prompt user for second corner of area to zoom. A point
- selected outside of the drawing area is an invalid point
- selection and the user is reprompt for a selection. */
- location = GetLocationInDrawport (info,
- "Select second corner of area to zoom.");
- FOREVER
- {
- point = (DV_POINT *) VOloWcpGet (location);
- if (!point)
- location = GetLocationInDrawport (info,
- "Invalid point selection.\n Pick corner point in drawing area.");
- else if ((point->x == ZoomVp.ll.x) || (point->y == ZoomVp.ll.y))
- location = GetLocationInDrawport (info,
- "Zoom rectangle has zero length on one side.\n Pick a different corner point.");
- else
- break;
- }
- ZoomVp.ur.x = point->x;
- ZoomVp.ur.y = point->y;
-
- /* Set the message string back to the original message. */
- VOtxSetString (info->MessageString, old_msg);
- S_FREE (old_msg);
- TdpDrawObject (info->main_dp, info->MessageString);
-
- VOuVpSort (&ZoomVp);
- TdpZoomTo (info->view_dp, &ZoomVp);
- }
-
-
-
- /*------------------------
- * GetLocationInDrawport -- Prompt user to select point in viewing
- * drawport. The parameter msg represents the prompt to be
- * displayed to the user.
- */
- LOCAL OBJECT
- GetLocationInDrawport (info, msg)
- INFO *info;
- char *msg;
- {
- char *old_msg;
- OBJECT location;
-
- old_msg = VUstrClone (VOtxGetString (info->MessageString));
- TdpEraseObject (info->main_dp, info->MessageString);
- VOtxSetString (info->MessageString, msg);
- TdpDrawObject (info->main_dp, info->MessageString);
-
- VOscWinEventMask ((ULONG) V_BUTTONPRESS | V_RESIZE | V_EXPOSE, (ULONG) 0);
- VOinState (info->menu_obj, INACTIVE);
- VOinState (info->vscroll_obj, INACTIVE);
- VOinState (info->hscroll_obj, INACTIVE);
-
- while (1)
- {
- location = VOloWinEventPoll (V_WAIT);
- if (VUerHandleLocEvent (location) == INPUT_UNUSED)
- {
- if (TloGetSelectedDrawport (location) != info->view_dp)
- continue;
- break;
- }
- }
- TdpEraseObject (info->main_dp, info->MessageString);
- VOtxSetString (info->MessageString, old_msg);
- S_FREE (old_msg);
- TdpDrawObject (info->main_dp, info->MessageString);
-
- VOscWinEventMask ((ULONG) V_KEYPRESS | V_BUTTONPRESS
- | V_EXPOSE | V_RESIZE | V_MOTIONNOTIFY,
- (ULONG) 0);
- VOinState (info->menu_obj, ACTIVE);
- VOinState (info->vscroll_obj, ACTIVE);
- VOinState (info->hscroll_obj, ACTIVE);
-
- return location;
- }
-